package com.panopset.games.playingcards;

import java.util.ArrayList;
import java.util.List;

import com.panopset.centralen.util.MathUtil;

/**
 * Multiple deck shoe.
 *
 * @author Karl Dinwiddie
 *
 */
public class Shoe {

    private final Integer numberOfDecks;
    public Long numberOfShuffles = 0L;
    private List<Deck> decks;

    public Shoe(final Integer numberOfDecks) {
        this.numberOfDecks = numberOfDecks;
        shuffle();
    }

    public void shuffle() {
        decks = new ArrayList<Deck>();
        numberOfShuffles++;
        for (int i = 0; i < numberOfDecks; i++) {
            decks.add(new Deck());
        }
    }

    public Card deal() {
        if (stackedDeckForTesting.size() > 0) {
            return stackedDeckForTesting.remove(0);
        }
        // if (remaining() < 1) {
        // throw new ArrayIndexOutOfBoundsException();
        // }
        int i = MathUtil.random(0, decks.size() - 1);
        Deck deck = decks.get(i);
        Card rtn = deck.deal();
        if (deck.remaining() < 1) {
            decks.remove(i);
        }
        return rtn;
    }

    public int remaining() {
        int rtn = 0;
        for (Deck deck : decks) {
            rtn += deck.remaining();
        }
        return rtn;
    }

    static List<Card> stackedDeckForTesting = new ArrayList<Card>();
    {

        // Resplit aces
        // stackedDeckForTesting.add(Card.ACE_OF_SPADES);
        // stackedDeckForTesting.add(Card.THREE_OF_DIAMONDS);
        // stackedDeckForTesting.add(Card.ACE_OF_HEARTS);
        // stackedDeckForTesting.add(Card.KING_OF_HEARTS);
        // stackedDeckForTesting.add(Card.THREE_OF_DIAMONDS);
        // stackedDeckForTesting.add(Card.ACE_OF_DIAMONDS);

        // Soft 18 vs 3t4
        // stackedDeckForTesting.add(Card.ACE_OF_SPADES);
        // stackedDeckForTesting.add(Card.THREE_OF_DIAMONDS);
        // stackedDeckForTesting.add(Card.SEVEN_OF_DIAMONDS);
        // stackedDeckForTesting.add(Card.KING_OF_HEARTS);
        // stackedDeckForTesting.add(Card.THREE_OF_DIAMONDS);
        // stackedDeckForTesting.add(Card.FOUR_OF_HEARTS);

        // All tens...
        // stackedDeckForTesting.add(Card.TEN_OF_SPADES);
        // stackedDeckForTesting.add(Card.TEN_OF_SPADES);
        // stackedDeckForTesting.add(Card.TEN_OF_SPADES);
        // stackedDeckForTesting.add(Card.TEN_OF_SPADES);
        // stackedDeckForTesting.add(Card.TEN_OF_SPADES);
        // stackedDeckForTesting.add(Card.TEN_OF_SPADES);
        // stackedDeckForTesting.add(Card.TEN_OF_SPADES);

        // Player 18, vs dealer t2q
        // stackedDeckForTesting.add(Card.EIGHT_OF_SPADES);
        // stackedDeckForTesting.add(Card.TEN_OF_SPADES);
        // stackedDeckForTesting.add(Card.TEN_OF_SPADES);
        // stackedDeckForTesting.add(Card.TWO_OF_HEARTS);
        // stackedDeckForTesting.add(Card.QUEEN_OF_SPADES);
        // stackedDeckForTesting.add(Card.EIGHT_OF_CLUBS);
        // stackedDeckForTesting.add(Card.EIGHT_OF_CLUBS);

        // Dealer blackjack:
        // stackedDeckForTesting.add(Card.FOUR_OF_SPADES);
        // stackedDeckForTesting.add(Card.TEN_OF_SPADES);
        // stackedDeckForTesting.add(Card.THREE_OF_SPADES);
        // stackedDeckForTesting.add(Card.ACE_OF_HEARTS);
        // stackedDeckForTesting.add(Card.QUEEN_OF_SPADES);
        // stackedDeckForTesting.add(Card.EIGHT_OF_CLUBS);
        // stackedDeckForTesting.add(Card.EIGHT_OF_CLUBS);
        // stackedDeckForTesting.add(Card.EIGHT_OF_CLUBS);
        // stackedDeckForTesting.add(Card.EIGHT_OF_CLUBS);

        // Player blackjack:
        // stackedDeckForTesting.add(Card.TEN_OF_SPADES);
        // stackedDeckForTesting.add(Card.FOUR_OF_SPADES);
        // stackedDeckForTesting.add(Card.ACE_OF_HEARTS);
        // stackedDeckForTesting.add(Card.THREE_OF_SPADES);
        // stackedDeckForTesting.add(Card.QUEEN_OF_SPADES);
        // stackedDeckForTesting.add(Card.EIGHT_OF_CLUBS);
        // stackedDeckForTesting.add(Card.EIGHT_OF_CLUBS);
        // stackedDeckForTesting.add(Card.EIGHT_OF_CLUBS);
        // stackedDeckForTesting.add(Card.EIGHT_OF_CLUBS);

        // stackedDeckForTesting.add(Card.ACE_OF_HEARTS);
        // stackedDeckForTesting.add(Card.ACE_OF_CLUBS);
        // stackedDeckForTesting.add(Card.ACE_OF_DIAMONDS);
        // stackedDeckForTesting.add(Card.ACE_OF_SPADES);
    }
}
